﻿#region directives

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.IsolatedStorage;
using System.Security.Cryptography;
using System.Text;
using System.Xml.Serialization;
using Microsoft.Office.Interop.Outlook;
using Sync.Outlook;
using ToodleDo;
using Account = Toodledo.Model.Account;
using Exception = System.Exception;
using Folder = Toodledo.Model.Folder;

#endregion

namespace Sync
{
    public static class SyncSessionWrapper
    {
        private const string Filename = "syncsession.xml";
        private static SyncSession _syncsession;
        private static readonly IsolatedStorageFile Store = IsolatedStorageFile.GetUserStoreForAssembly();

        public static SyncSession SyncSession
        {
            get { return _syncsession ?? (_syncsession = LoadSession()); }
        }

        public static void Save()
        {
            IsolatedStorageFileStream stream = null;
            try
            {
                SyncSession.UpdateSession();
                //assureDirectoryExists<ItemType>();//todo exception handling
                XmlSerializer serializer = new XmlSerializer(typeof(SyncSession));
                stream = new IsolatedStorageFileStream(Filename, FileMode.Create, Store);
                if (SyncSession != null) serializer.Serialize(stream, SyncSession);                
            }
            catch (Exception e)
            {
                Logger.InvokeMessageEvent(e.Message,Logger.MessageType.Tracking);                
            }
            finally
            {
                if (stream != null) stream.Close();
            }
            
        }

        private static SyncSession LoadSession()
        {
            SyncSession ss = null;
            IsolatedStorageFileStream stream = null;
            if (Store.FileExists(Filename))
            {
                try
                {
                    stream = new IsolatedStorageFileStream(Filename, FileMode.Open, Store);
                    XmlSerializer serializer = new XmlSerializer(typeof (SyncSession));
                    ss = serializer.Deserialize(stream) as SyncSession;
                }
                catch (Exception e)
                {
                    Logger.InvokeMessageEvent(e.Message, Logger.MessageType.Tracking);   
                }
                finally
                {
                    if (stream != null) stream.Close();
                }
            }
            return ss ?? new SyncSession();
        }
    }

    public class SyncSession
    {
        public SyncSession()
        {
            TaskIds = new List<int>();
            Folders = new List<Folder>();
        }

        public DateTime LastAddEdit { get; set; }
        public List<int> TaskIds { get; set; }
        public string CategoryHash { get; set; }
        public DateTime LastSyncUtc { get; set; }
       

        public List<Folder> Folders { get; set; }

        public Folder GetFolder(int id)
        {
            return Folders.Find(f => f.Id == id);
        }

        public static string CalculateCategoryHash(IEnumerable<Category> categories)
        {
            StringBuilder sb1 = new StringBuilder();
            foreach (Category category in categories)
            {
                sb1.Append(category.Name);
            }
            string input = sb1.ToString();
            // step 1, calculate MD5 hash from input
            MD5 md5 = MD5.Create();
            byte[] inputBytes = Encoding.ASCII.GetBytes(input);
            byte[] hash = md5.ComputeHash(inputBytes);

            // step 2, convert byte array to hex string
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hash.Length; i++)
            {
                sb.Append(hash[i].ToString("X2"));
            }
            return sb.ToString();
        }

        public void UpdateSession()
        {
            Remote.Session.Account = Remote.Authentication.GetAccountInfo();
            if (Remote.Session != null)
            {
                Account account = Remote.Session.Account;
                LastAddEdit = account.LastTaskEdit; //todo make sure the account info refreshes after each cycle.
                LastSyncUtc = DateTime.UtcNow; //don;t need it, can get all new adds since last server update!                
            }
            Debug.WriteLine(LastAddEdit);
            TaskIds.Clear();
            foreach (TaskItem item in TasksItems.All)
            {
                TaskIds.Add(item.GetId());
            }
            Logger.InvokeMessageEvent(String.Format("Outlook tasks stored: {0}", TaskIds.Count),Logger.MessageType.Tracking);
        }

        public Folder GetFolder(string name)
        {
            return Folders.Find(f => f.Name == name);
        }
    }
}